package com.wwinsoft.framework.web.workflow;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.diagram.ProcessDiagramGenerator;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.io.IOUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.springframework.beans.factory.annotation.Autowired;

import com.wwinsoft.framework.web.SimpleActionSupport;
import com.wwinsoft.modules.utils.web.struts2.Struts2Utils;

/**
 * @author: Tim Chen
 * @since 1.0
 */
@Namespace("/workflow")
public class ProcessAction extends SimpleActionSupport {

    @Autowired
    private TaskService taskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    private static final int BUFFER_SIZE = 16 * 1024;

    private File deployFile;
    private String deployFileContentType;
    private String deployFileFileName;

    public void setDeployFile(File deployFile) {
        this.deployFile = deployFile;
    }

    public void setDeployFileContentType(String deployFileContentType) {
        this.deployFileContentType = deployFileContentType;
    }

    public void setDeployFileFileName(String deployFileFileName) {
        this.deployFileFileName = deployFileFileName;
    }

    public void deployUploadedFile() {
        DeploymentBuilder deploymentBuilder;
        try {
            deploymentBuilder = repositoryService.createDeployment().name(deployFileFileName);
            InputStream inputStream = new FileInputStream(deployFile);
            if (deployFileFileName.endsWith(".bar")
                || deployFileFileName.endsWith(".zip")
                || deployFileFileName.endsWith(".jar")) {
                deploymentBuilder.addZipInputStream(new ZipInputStream(inputStream));
            } else {
                deploymentBuilder.addInputStream(deployFileFileName, inputStream);
            }
        } catch (IOException e) {
            throw new ActivitiException("couldn't auto deploy resource '" + deployFileFileName + "': " + e.getMessage(),
                                        e);
        }
        deploymentBuilder.deploy();
    }

    public void processImage() throws Exception {
        String processInstanceId = Struts2Utils.getParameter("processInstanceId");
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(
                processInstanceId).singleResult();
        InputStream definitionImageStream = null;
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(
                processInstance.getProcessDefinitionId());
        if (processDefinition != null && processDefinition.isGraphicalNotationDefined()) {
            definitionImageStream = ProcessDiagramGenerator.generateDiagram(processDefinition, "png",
                                                                            runtimeService.getActiveActivityIds(
                                                                                    processInstance.getId()));
        }
        String imageExtension = extractImageExtension(processDefinition.getDiagramResourceName());
        String fileName = processInstance.getId() + UUID.randomUUID() + "." + imageExtension;
        HttpServletResponse response = Struts2Utils.getResponse();
        ServletOutputStream out = response.getOutputStream();
        byte[] bytes = null;
        response.setContentType("multipart/form-data");
        bytes = new byte[1024];
        while (-1 != definitionImageStream.read(bytes)) {
            out.write(bytes);
            out.flush();
        }
        IOUtils.closeQuietly(out);
    }

    protected String extractImageExtension(String diagramResourceName) {
        String[] parts = diagramResourceName.split(".");
        if (parts.length > 1) {
            return parts[parts.length - 1];
        }
        return "png";
    }

}
